#pragma once
#include "GRendererInfra/GRiTimer.h"
#include "GDX11Renderer/GDxRenderer.h"
#include <memory>
#include "GRendererInfra/GRiCamera.h"
#include "GRendererInfra/GRiTexture.h"
#include <unordered_map>
#include "GScene.h"
#include <GRendererInfra\GRiMesh.h>
#include <GDX11Renderer\GDxImgui.h>
#include <GGenericInfra/GPtr.h>
#include <GRendererInfra/GRiObj.h>

class GCore
{
public:
	GCore(const GCore& rhs) = delete;
	GCore& operator=(const GCore& rhs) = delete;
	~GCore();

	static GCore& GetCore();

	void Run();
	void RenderFrame();

	void Initialize(HWND OutputWindow, double width, double height);

	void MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

	// export
	void SaveScene();

	int GetSceneObjectNum();

	const char* GetSceneObjectName(int index);

	void SelectSceneObject(char* sceneObjectName);
	
	void  CreateSceneObject(char* sceneObjectName, char* meshUniqueName);

	bool SceneObjectExists(char* tryName) const;

	void DeleteSceneObject(char* deleteName) ;
	
	void SetProjectName(char* projName);

	void GetSceneObjectTransform(char* objName, float* trans);

	void SetSceneObjectTransform(char* objName, float* trans);

	const char* GetSceneObjectMeshName(char* objName);

	void SetSceneObjectMesh(char* sceneObjectName, char* meshUniqueName);

	void SetExternData(UINT ini) {
		mINI = ini;
		mRenderer->SetExternData(mINI);
	}
protected:
	// 设置属性
	UINT mINI = INI_UseSky | INI_UseIMGUI | INI_UseDeferredOut;

private:

	bool      mAppPaused = false;  // is the application paused?
	bool      mMinimized = false;  // is the application minimized?
	bool      mMaximized = false;  // is the application maximized?
	bool      mResizing = false;   // are the resize bars being dragged?
	bool      mFullscreenState = false;// full screen enabled

	GRiRenderer* mRenderer;

	GRiRendererFactory* mFactory;

	std::unique_ptr<GRiCamera>			m_pCamera;
	CameraMode m_CameraMode;			// 摄像机模式

	std::unique_ptr<GRiTimer> mTimer;

	// Texture
	std::unordered_map<std::string, std::unique_ptr<GRiTexture>> mTextures;
	std::unordered_map<std::string, std::unique_ptr<GRiMaterial>> mMaterials;
	std::unordered_map<std::string, std::unique_ptr<GRiMesh>> mMeshes;
	std::unordered_map<std::string, std::unique_ptr<GRiObj>> mSceneObjects;
	std::vector<GRiObj*>mSceneObjectLayer[(int)RenderLayer::Count];


	std::unique_ptr<GRiImgui> mImgui;

	std::unique_ptr<GScene> mScene;
	std::string ProjectName;

	GUSPtr<GRiObj> mSelectedSceneObject;

	float mCameraSpeed = 150.0f;
protected:
#pragma region Initialize Func

	void LoadScene();
	
	void CreateImgui();


	bool LoadAllTexture();

	void LoadMaterials();

	void LoadMeshes();

	void LoadSceneObjects();

	void LoadCamera();


#pragma endregion Initialize
	
	std::string WorkDir;
	std::string mSkyCubeFileName;
	
	std::vector<std::string> FindFileInFolder(const std::string& relPath,const std::vector<std::string>& formats,bool bCheckFormat = false);
protected:

	void OnResize();

	void Update();
	void UpdateCamera();
	void UpdateGui();
	void Draw();



	//void SaveScene();
private:
	GCore();
};

